using System;
using System.Diagnostics;
using Arroguella.Entities;
using Arroguella.Panels;
using Arroguella.Tiles;
using Arroguella.Utilities;
using Microsoft.Xna.Framework;

namespace Arroguella
{
    /// <summary>
    /// This class handles all combat
    /// </summary>
    public class CombatEngine
    {
        #region Constructor

        public CombatEngine(Game game, TileEngine tileEngine)
        {
            Arroguella = game as Arroguella;
            TileEngine = tileEngine;
        }

        #endregion

        #region Melee Combat

        /// <summary>
        /// Performs a single round of combat.
        /// The two combatants first roll for initiative to see who goes first.
        /// The first combatant performs one attack, then the second combatant performs one attack.
        /// </summary>
        public void PerformRoundOfMeleeCombat(Player player, CreatureEntity monster)
        {
            Debug.WriteLine("Round of melee combat");
            // Don't attack dead things
            if (monster.CurrentHealth <= 0)
            {
                return;
            }

            // Can't really attack stuff without AI
            if (monster.Ai == null)
            {
                return;
            }

            monster.Ai.Attacked = true;

            int playerInitiative = Dice.D(20) + player.Agility;
            int monsterInitiative = Dice.D(20) + monster.Agility;

            Debug.WriteLine(string.Format("Player INIT {0} vs {1} INIT {2}", playerInitiative, monster.Name, monsterInitiative));

            // Player wins initiative - player attacks first, then monster.
            if (playerInitiative >= monsterInitiative)
            {
                if (player.PrimaryWeapon != null)
                {
                    ArmedMeleeAttack(player, monster);
                }
                else
                {
                    UnarmedMeleeAttack(player, monster);
                }

                if (monster.CurrentHealth > 0)
                {
                    UnarmedMeleeAttack(monster, player);
                }
            }
            // Monster wins initiative - monster attacks first, then player.
            else
            {
                UnarmedMeleeAttack(monster, player);
                if (player.CurrentHealth > 0)
                {
                    if (player.PrimaryWeapon != null)
                    {
                        ArmedMeleeAttack(player, monster);
                    }
                    else
                    { 
                        UnarmedMeleeAttack(player, monster); 
                    }
                }
            }

            Debug.WriteLine(string.Format("Player HP {0}/{1}\n{2} HP {3}/{4}", player.CurrentHealth, player.MaxHealth, monster.Name, monster.CurrentHealth, monster.MaxHealth));

            if (player.CurrentHealth <= 0)
            {
                player.OnDeath();                
            }

            if (monster.CurrentHealth <= 0)
            {
                CombatPanel.Message(string.Format("You killed {0}! (+{1} XP)", monster.Name, monster.Xp), Color.Purple);
                player.XP += monster.Xp;
                monster.Die();
            }
        }

        private void ArmedMeleeAttack(object attacker, object target)
        {
            Player player;
            CreatureEntity monster;

            if (attacker is Player && target is CreatureEntity)
            {
                player = attacker as Player;
                monster = target as CreatureEntity;

                EquipmentEntity primary = player.PrimaryWeapon;
                EquipmentEntity secondary = player.SecondaryWeapon;
                float attack;
                int damage;

                // Primary attack
                attack = Dice.D(20) + player.Agility + player.Skills["Melee Accuracy"] + primary.AccuracyModifier;
                Debug.WriteLine(string.Format("Player primary ATTACK {0} vs {1} DEFENSE {2}", attack, monster.Name, monster.Defense));
                if (attack > monster.Defense)
                {
                    damage = Dice.Damage(primary.MinDamage, primary.MaxDamage) + player.Strength + primary.DamageModifier;
                    monster.CurrentHealth -= damage;
                    CombatPanel.Message(string.Format("You hit {0} with {1}! ({2} damage)", monster.Name, primary.Name, damage), Color.Lime);
                }
                else
                {
                    CombatPanel.Message(string.Format("You miss {0}.", monster.Name), Color.Gray);
                }

                // Secondary attack - if applicable.
                if (secondary != null && monster.CurrentHealth > 0)
                {
                    attack = Dice.D(20) + player.Agility + player.Skills["Melee Accuracy"] + secondary.AccuracyModifier;
                    Debug.WriteLine(string.Format("Player secondary ATTACK {0} vs {1} DEFENSE {2}", attack, monster.Name, monster.Defense));
                    if (attack > monster.Defense)
                    {
                        damage = Dice.Damage(secondary.MinDamage, secondary.MaxDamage) + player.Strength + secondary.DamageModifier;
                        monster.CurrentHealth -= damage;
                        CombatPanel.Message(string.Format("You hit {0} with {1}! ({2} damage)", monster.Name, secondary.Name, damage), Color.Lime);
                    }
                    else
                    {
                        CombatPanel.Message(string.Format("You miss {0}.", monster.Name), Color.Gray);
                    }
                }
            }
            else if (attacker is CreatureEntity && target is Player)
            {
                player = target as Player;
                monster = attacker as CreatureEntity;

                float attack = Dice.D(20) + monster.Agility;
                Debug.WriteLine(string.Format("{0} ATTACK {1} vs Player DEFENSE {2}", monster.Name, monster.Defense, player.Defense + player.DefenseModifierFromEquipment));
                if (attack > player.Defense + player.DefenseModifierFromEquipment)
                {
                    int damage = Dice.D(4) + monster.Strength;
                    player.CurrentHealth -= damage;
                    CombatPanel.Message(string.Format("{0} hit you! ({1} damage)", monster.Name, damage), Color.IndianRed);
                }
                else
                {
                    CombatPanel.Message(string.Format("{0} missed you.", monster.Name), Color.Gray);
                }
            }
        }

        private void UnarmedMeleeAttack(object attacker, object target)
        {
            Player player;
            CreatureEntity monster;

            if (attacker is Player && target is CreatureEntity)
            {
                player = attacker as Player;
                monster = target as CreatureEntity;

                float attack = Dice.D(20) + player.Agility + player.Skills["Melee Accuracy"] + player.AccuracyModifierFromEquipment;
                Debug.WriteLine(string.Format("Player ATTACK {0} vs {1} DEFENSE {2}", attack, monster.Name, monster.Defense));
                if (attack > monster.Defense)
                {
                    int damage = Dice.D(4) + player.Strength + player.DamageModifierFromEquipment;
                    monster.CurrentHealth -= damage;
                    CombatPanel.Message(string.Format("You hit {0}! ({1} damage)", monster.Name, damage), Color.Lime);
                }
                else
                {
                    CombatPanel.Message(string.Format("You miss {0}.", monster.Name), Color.Gray); 
                }
            }
            else if (attacker is CreatureEntity && target is Player)
            {
                player = target as Player;
                monster = attacker as CreatureEntity;

                float attack = Dice.D(20) + monster.Agility;
                Debug.WriteLine(string.Format("{0} ATTACK {1} vs Player DEFENSE {2}", monster.Name, monster.Defense, player.Defense + player.DefenseModifierFromEquipment));
                if (attack > player.Defense + player.DefenseModifierFromEquipment)
                {
                    int damage = Dice.D(4) + monster.Strength;
                    player.CurrentHealth -= damage;
                    CombatPanel.Message(string.Format("{0} hit you! ({1} damage)", monster.Name, damage), Color.IndianRed);
                }
                else
                {
                    CombatPanel.Message(string.Format("{0} missed you.", monster.Name), Color.Gray);
                }
            }
        }

        #endregion

        #region Methods

        public void Update(GameTime gameTime)
        {
            // TODO: Add your update code here
        }

        #endregion

        #region Properties

        private TileEngine TileEngine { get; set; }

        private Arroguella Arroguella { get; set; }

        private MessagePanel CombatPanel { get { return Arroguella.GameScreen.CombatPanel; } }

        #endregion

    }
}
